/**
 * 2009-10-20 下午05:48:20 
 * esignature
 * com.smc.server.impl
 * DocumentServiceImpl
 */
package com.smc.server.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.apache.struts2.ServletActionContext;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.smc.action.document.NumDocument;
import com.smc.action.document.PdfDocument;
import com.smc.dao.DocumentDao;
import com.smc.domain.model.Certification;
import com.smc.domain.model.Document;
import com.smc.domain.model.Hospital;
import com.smc.domain.model.User;
import com.smc.security.SecurityContextHolder;
import com.smc.server.CertificationService;
import com.smc.server.DocumentService;
import com.smc.server.HospitalService;
import com.smc.server.UserService;

/**
 * @author chenheng
 * @version 0.0.1
 * 文档服务接口实现。具体参见文档服务接口。
 */
public class DocumentServiceImpl implements DocumentService {
	/**
	 * 文档Dao接口
	 */
	private DocumentDao documentDao ;
	/**
	 * 医院服务接口
	 */
	private HospitalService hospitalService ;
	/**
	 * 证书操作接口
	 */
	private com.smc.signature.Certificate certificate ;
	/**
	 * 证书服务接口
	 */
	private CertificationService certService ;
	/**
	 * 用户服务接口
	 */
	private UserService userService ;
	/**
	 * pdf文件路径
	 */
	private String pdfPath ;
	/**
	 * 原始文档路径
	 */
	private String originalFolder ;
	/**
	 * 签名文档路径
	 */
	private String signedFolder ;
	/**
	 * 未签名文档路径
	 */
	private String unSignedFolder ;
	/**
	 * 签名证书路径
	 */
	private String certPath ;
	/**
	 * 签名证书类型
	 */
	private String certType ;
	/**
	 * 签名证书密码
	 */
	private String certPassword ;
	
	
	
	public CertificationService getCertService() {
		return certService;
	}

	public void setCertService(CertificationService certService) {
		this.certService = certService;
	}

	public com.smc.signature.Certificate getCertificate() {
		return certificate;
	}

	public void setCertificate(com.smc.signature.Certificate certificate) {
		this.certificate = certificate;
	}

	public HospitalService getHospitalService() {
		return hospitalService;
	}

	public void setHospitalService(HospitalService hospitalService) {
		this.hospitalService = hospitalService;
	}
	
	
	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public DocumentDao getDocumentDao() {
		return documentDao;
	}

	public void setDocumentDao(DocumentDao documentDao) {
		this.documentDao = documentDao;
	}
	
	
	public String getPdfPath() {
		return pdfPath;
	}

	public void setPdfPath(String pdfPath) {
		this.pdfPath = pdfPath;
	}

	public String getOriginalFolder() {
		return originalFolder;
	}

	public void setOriginalFolder(String originalFolder) {
		this.originalFolder = originalFolder;
	}

	public String getSignedFolder() {
		return signedFolder;
	}

	public void setSignedFolder(String signedFolder) {
		this.signedFolder = signedFolder;
	}

	public String getUnSignedFolder() {
		return unSignedFolder;
	}

	public void setUnSignedFolder(String unSignedFolder) {
		this.unSignedFolder = unSignedFolder;
	}
	
	public String getCertPassword() {
		return certPassword;
	}

	public void setCertPassword(String certPassword) {
		this.certPassword = certPassword;
	}

	public String getCertPath() {
		return certPath;
	}

	public void setCertPath(String certPath) {
		this.certPath = certPath;
	}

	public String getCertType() {
		return certType;
	}

	public void setCertType(String certType) {
		this.certType = certType;
	}

	public void sign_US_DO_SI_document(Document document,String[] parameters) {
		String src = pdfPath + unSignedFolder + document.getFileName();
		String dist = pdfPath + signedFolder + document.getFileName();
		boolean flag = false ;
		try {
			Certification cert = certService.fetch_US_CE_FE_certification(parameters[0]);
			String alias = cert.getAlias();
			String keypass = cert.getKeypass();
			String[] params = new String[]{alias,keypass,src,dist,parameters[1],parameters[2]};
			flag = certificate.sign(params);
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
		if (flag) {
			File f = new File(src);
			if ( f.exists() ) {
				f.delete();
			}
			document.setSigned(flag);
			document.setSignTime(new Timestamp(System.currentTimeMillis()));
			documentDao.save_US_DO_SA_document(document);
		}
	}
	
	public List<Document> fetch_US_DO_FE_document(boolean signed,int pageIndex,int pageSize) {
		String uuid = SecurityContextHolder.getAuthentication(ServletActionContext.getRequest().getSession()).getUUUID().toString();
		List<Document> list = documentDao.fetch_US_DO_FE_document(signed,uuid,pageIndex,pageSize);
		return list;
	}
	

	public int count_US_DO_FE_document(boolean signed) {
		String uuid = SecurityContextHolder.getAuthentication(ServletActionContext.getRequest().getSession()).getUUUID().toString();
		return documentDao.count_US_DO_FE_document(signed, uuid);
	}
	
	public void save_OP_DO_SA_document(Document document) {
		String src = pdfPath + originalFolder + document.getFileName();
		String dist = pdfPath + unSignedFolder + document.getFileName();
		if (movePdfFile(src, dist)) {
			File f = new File(src);
			if ( f.exists()) {
				f.delete();
			}
			documentDao.save_OP_DO_SA_document(document);
		}
	}

	public List<PdfDocument> fetch_OP_DO_FE_document() {
		List<PdfDocument> pdfList = new ArrayList<PdfDocument>();
		File originalPdfFolder = new File(pdfPath + originalFolder);
		if (originalPdfFolder.isDirectory()) {
			for ( File f : originalPdfFolder.listFiles()) {
				if ( f.isFile()) {
					PdfDocument pd = new PdfDocument();
					pd.setFileName(f.getName());
					pd.setLastModified(f.lastModified());
					pd.setSize(f.length());
					pdfList.add(pd);
				}
			}
		}
		return pdfList;
	}

	public List<Hospital> fetch_OP_HO_FE_hospital() {
		return hospitalService.fetch_OP_HO_FE_hospital();
	}

	public List<User> fetch_OP_US_FE_user(String hospitalUuid) {
		return userService.fetch_OP_US_FE_user(hospitalUuid);
	}

	public Document fetch_US_DO_FE_document(String uuid) {
		Document d = documentDao.fetch_US_DO_FE_document(uuid);
		return d;
	}
	
	private boolean movePdfFile(String src,String dist) {
		boolean flag = false ;
		try {
			PdfReader reader = new PdfReader(src);
			int pageNumber = reader.getNumberOfPages();
			com.lowagie.text.Document document = new com.lowagie.text.Document(reader.getPageSize(1));
			PdfCopy copy = new PdfCopy(document, new FileOutputStream(dist));
			document.open();
			for ( int i = 1 ; i <= pageNumber ; i ++ ) {
				document.newPage();
				PdfImportedPage page = copy.getImportedPage(reader, i);
				copy.addPage(page);
			}
			document.close();
			flag = true ;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return flag ;
	}

	public List<Document> fetch_HO_DO_FE_document(String hospitalUuid, boolean sigend, int pageIndex, int pageSize) {
		List<Document> ld = documentDao.fetch_HO_DO_FE_document(hospitalUuid, sigend, pageIndex, pageSize);
		return ld;
	}

	public List<Document> fetch_HO_DO_FE_document(String hospitalUuid, String[] parameters, int pageIndex, int pageSize) {
		List<Document> ld = documentDao.fetch_HO_DO_FE_document(hospitalUuid, parameters, pageIndex, pageSize);
		return ld;
	}

	public List<NumDocument> fetch_HO_DO_FE_documentNum(String hospitalUuid, String orderItem, int pageIndex, int pageSize) {
		List<NumDocument> ld = documentDao.fetch_HO_DO_FE_documentNum(hospitalUuid, orderItem, pageIndex, pageSize);
		return ld;
	}

	public int count_HO_DO_FE_documentNum(String uuid) {
		return documentDao.count_HO_DO_FE_documentNum(uuid);
	}

	public List<NumDocument> fetch_HO_DO_FE_documentRankNum(String uuid,String orderItem, int pageIndex, int pageSize) {
		return documentDao.fetch_HO_DO_FE_documentRankNum(uuid, orderItem, pageIndex, pageSize);
	}

	public List<NumDocument> fetch_HO_DO_FE_documentPatientNum(String uuid, String orderItem, int pageIndex, int pageSize) {
		return documentDao.fetch_HO_DO_FE_documentPatientNum(uuid, orderItem, pageIndex, pageSize);
	}

	public int count_HO_DO_FE_documentNum(String uuid, boolean signed) {
		return documentDao.count_HO_DO_FE_documentNum(uuid,signed);
	}

	public int count_HO_DO_FE_document(String uuid, String[] parameters) {
		return documentDao.count_HO_DO_FE_document(uuid, parameters);
	}

}
